package com.kylin.common.core.interceptor;

import com.kylin.common.core.annotation.JSONSerialized;
import com.kylin.common.core.annotation.JSONSerializedGroup;
import com.kylin.common.core.beans.ResultBean;
import com.kylin.common.core.filter.ApiLogExtend;
import com.kylin.common.core.filter.ApiLogThreadLocal;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.lang.reflect.Method;

/**
 * API请求接口统一拦截器
 *
 * @author wuhao
 * @version 1.0 - 2019/6/25
 */
@Component("apiInterceptor")
@Aspect
@Order(1)
public class ApiInterceptor {

    private Logger logger = LoggerFactory.getLogger("API");

    /**
     * 拦截app目录下的请求方法
     * @author wuhao
     * @since 1.0.0 - 2019/6/25
     */
    @Pointcut("execution( * com..controller..*(..)) && !@annotation(com.kylin.common.core.annotation.NoApiInterceptor)")
    public void apiInterceptor(){
        // Do nothing
    }

    @Around("apiInterceptor()")
    public ResultBean<Serializable> doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
        long startTime = System.currentTimeMillis();
        ResultBean<Serializable> resultBean = null;
        try {
            // 请求参数
            Object[] params = pjp.getArgs();

            // 执行请求
            resultBean = (ResultBean<Serializable>) pjp.proceed(params);

            //设置序列化
            MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
            Method method = methodSignature.getMethod();

            // 支持两种注解
            JSONSerializedGroup jsonFilter = method.getAnnotation(JSONSerializedGroup.class);
            if(jsonFilter != null){
                JSONSerialized[] jsonSerializeds = jsonFilter.value();
                resultBean.setJsonSerialized(jsonSerializeds);
            }

            // 序列化输出
            JSONSerialized jsonSerialized = method.getAnnotation(JSONSerialized.class);
            if(jsonSerialized != null){
                resultBean.setJsonSerialized(new JSONSerialized[]{jsonSerialized});
            }

        }catch (Throwable e){
//            e.printStackTrace();
            // 抛出异常，让其在exceptionadvice处理
            ApiLogExtend apiLogExtend = ApiLogThreadLocal.getContext();
            apiLogExtend.setException(e.getMessage());
            ApiLogThreadLocal.setContext(apiLogExtend);
            throw e;
        }finally {
            // 日志统计放在apifilter中处理，否则springsecurit里面的日志拦截不到
//            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//            if(!Objects.isNull(requestAttributes)) {
//                HttpServletRequest request = requestAttributes.getRequest();
//                //日志分类,可根据不用的属性分类日志
//                String inParams = JSON.toJSONString(ObjectUtils.isEmpty(pjp.getArgs()) ? request.getParameterMap() : pjp.getArgs());
//                String result = JSON.toJSONString(resultBean);
//                logger.info("\n【接口名称】: {} \n【接口路径】：{} \n【接口入参】：{} \n【接口出参】：{} \n【接口耗时】：{} ms",
//                        pjp.getSignature().getName(),
//                        pjp.getStaticPart().getSignature().getDeclaringTypeName(),
//                        inParams,
//                        result,
//                        (System.currentTimeMillis() - startTime));
//            }
        }
        return  resultBean;
    }

}
